#!/usr/bin/env python

""" 
    Support Operator Classes

    Base Class: RTLOperator
    Concrete Classes: 
        OpBinary
        OpUnary
        OpRout
        OpFunc
        OpCall
        OpRet
"""

__author__ = 'liwei79@gmail.com'

_BINARY_OPCODES = (
    "ADD", "SUB", "STAR", "DIV", "MOD",
    "BOR", "BAND", "BXOR", "BNAND", "BNOR", "BXNOR",    
    "EQ", "NE", "GT", "GE", "LT", "LE",
    "RSHFT", "LSHFT", 
    "LAND", "LOR", 
)

_UNARY_OPCODES = (
    "LOAD", "LOAD_IMM", "LOAD_IND", "STORE_IND",
    "ASSIGN",
    "BINV", "BNOT", 
    "USUB",
)

_MISC_OPCODES = (
    "ROUT", "CALL", "FUNC", "RET"
)

_OPCODES = _BINARY_OPCODES + _UNARY_OPCODES + _MISC_OPCODES
_OPCODES_map = {}

for _op in _OPCODES:
    _OPCODES_map[_op.upper()] = _op


def _IS_BOP(op):
    return  _OPCODES_map.has_key(op) and ( op in _BINARY_OPCODES)

def _IS_UOP(op):
    return  _OPCODES_map.has_key(op) and ( op in _UNARY_OPCODES)

def _IS_MISCOP(op):
    return  _OPCODES_map.has_key(op) and ( op in _MISC_OPCODES)

class RTLOperator:

    def __init__(self, op):
        self.op = op

    def __repr__(self):
        return repr(self.op)


class OpBinary(RTLOperator):

    def __init__(self, op):
        assert(_IS_BOP(op))
        RTLOperator.__init__(self, op)


class OpUnary(RTLOperator):

    def __init__(self, op):
        assert(_IS_UOP(op))
        RTLOperator.__init__(self, op)


class OpRout(RTLOperator):

    def __init__(self, op):
        assert(op == "ROUT")
        RTLOperator.__init__(self, op)


class OpFunc(RTLOperator):

    def  __init__(self, op):
        assert(op == "FUNC")
        RTLOperator.__init__(self, op)


class OpCall(RTLOperator):

    def  __init__(self, op):
        assert(op == "CALL")
        RTLOperator.__init__(self, op)


class OpRet(RTLOperator):

    def  __init__(self, op):
        assert(op == "RET")
        RTLOperator.__init__(self, op)


if __name__ == "__main__":
    o1 = OpBinary("ADD")
    print o1

